// FeedStory.cs
// Facebook/Framework/Service
// Copyright (c) 2007, Nikhil Kothari. All Rights Reserved.
//
// Total Re-write:
// Copyright (c) 2008, Paul Huff. All Rights Reserved.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

namespace Facebook.Service
{

    /// <summary>
    /// Represents a story that can be published to the news feed or mini-feed.
    /// </summary>
    public sealed class FeedStory
    {

        private string _bodyGeneral;
        private List<FeedImage> _images;
        private FeedStorySize _storySize;
        private ICollection<string> _targetUserIDs;
        private Hashtable _templateData;
        private int _templateBundleID;


        /// <summary>
        /// Initializes a feed story with the specified templateBundleID for the
        /// current application.
        /// </summary>
        /// <param name="templateBundleID"></param>
        public FeedStory(int templateBundleID)
        {
            if (templateBundleID <= 0)
            {
                throw new ArgumentNullException("templateBundleID");
            }

            _templateBundleID = templateBundleID;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="templateBundleID"></param>
        /// <param name="templateData"></param>
        public FeedStory(int templateBundleID, Hashtable templateData)
            :this( templateBundleID )
        {
            if (templateData == null)
            {
                throw new ArgumentNullException("templateData");
            }

            _templateData = templateData;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="templateBundleID"></param>
        /// <param name="templateData"></param>
        /// <param name="targetUserIDs"></param>
        public FeedStory(int templateBundleID, Hashtable templateData, ICollection<string> targetUserIDs)
            : this( templateBundleID,  templateData )
        {
            if (targetUserIDs == null)
            {
                throw new ArgumentNullException("targetUserIDs");
            }

            _targetUserIDs = targetUserIDs;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="templateBundleID"></param>
        /// <param name="templateData"></param>
        /// <param name="targetUserIDs"></param>
        /// <param name="bodyGeneral"></param>
        public FeedStory(int templateBundleID, Hashtable templateData, ICollection<string> targetUserIDs, string bodyGeneral)
            : this(  templateBundleID,  templateData,  targetUserIDs )
        {
     
            if (string.IsNullOrEmpty(bodyGeneral))
            {
                throw new ArgumentNullException("bodyGeneral");
            }

            _bodyGeneral = bodyGeneral;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="templateBundleID"></param>
        /// <param name="templateData"></param>
        /// <param name="targetUserIDs"></param>
        /// <param name="bodyGeneral"></param>
        /// <param name="storySize"></param>
        public FeedStory(int templateBundleID, Hashtable templateData, ICollection<string> targetUserIDs, string bodyGeneral, FeedStorySize storySize)
            : this(templateBundleID, templateData, targetUserIDs)
        {

            if (storySize == null)
            {
                throw new ArgumentNullException("storySize");
            }

            _storySize = storySize;
        }

        internal string BodyGeneral
        {
            get { return _bodyGeneral; }
        }

        internal ICollection<FeedImage> Images
        {
            get { return _images; }
        }

        internal ICollection<string> TargetUserIDs
        {
            get { return _targetUserIDs; }
        }

        internal Hashtable TemplateData
        {
            get { return _templateData; }
        }

        internal FeedStorySize StorySize
        {
            get { return _storySize; }
        }

        internal int TemplateBundleID
        {
            get { return _templateBundleID; }
        }

        /// <summary>
        /// Additional markup that extends the body of a short story. 
        /// If two or more short stories are aggregated into one story, 
        /// the markup in the body_general from any one of those stories may be displayed.
        /// </summary>
        /// <param name="body"></param>
        public void AddBodyGeneral(string body)
        {
            _bodyGeneral = body;
        }

        /// <summary>
        /// Adds the specified image to the story. A maximum of 4 images can be added.
        /// </summary>
        /// <param name="image">The image to be added.</param>
        public void AddImage(FeedImage image)
        {
            if (_images == null)
            {
                _images = new List<FeedImage>();
            }
            else if (_images.Count == 4)
            {
                throw new InvalidOperationException("A maximum of 4 images can be added.");
            }

            _images.Add(image);
        }

        /// <summary>
        /// Adds a value to replace the specified named placeholder in the template definition.
        /// This looks for named placeholders in both the title and body templates.
        /// </summary>
        /// <param name="name">The name of the placeholder to be replaced.</param>
        /// <param name="value">The value to use to fill the placeholder.</param>
        public void AddTemplateValue(string name, string value)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            if (String.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException("value");
            }

            if (_templateData == null)
            {
                _templateData = new Hashtable();
            }
            _templateData[name] = value;

        }
    }
}
